package com.goodmr.passport.account;

import lombok.NonNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.Optional;

/**
 * 帐号数据逻辑实现
 *
 * @author <a href="mailto:bingdong13@msn.com">bigo</a>
 */
@Service
public class AccountDaoImpl implements AccountDao {

    private final AccountRepository accountRepository;

    private final PlatformRepository platformRepository;

    @Autowired
    public AccountDaoImpl(AccountRepository accountRepository,
                          PlatformRepository platformRepository) {
        this.accountRepository = accountRepository;
        this.platformRepository = platformRepository;
    }

    /**
     * 创建帐号
     *
     * @param model 帐号平台信息
     * @return 帐号平台信息
     */
    @Override
    public PlatformModel generate(@NonNull PlatformModel model) {

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        model.setCreatedAt(timestamp);
        model.setUpdatedAt(timestamp);

        AccountEntity accountEntity = new AccountEntity();
        accountEntity.setAccount(model.getOpenId());
        accountEntity.setStatus(AccountStatusEnum.NORMAL.getValue());
        accountEntity.setCreatedAt(timestamp);
        accountEntity.setUpdatedAt(timestamp);

        accountEntity = accountRepository.save(accountEntity);

        PlatformEntity platformEntity = new PlatformEntity();
        BeanUtils.copyProperties(model, platformEntity);

        platformEntity.setAccountId(accountEntity.getId());
        platformEntity.setAccountType(model.getAccountType().getValue());
        platformEntity.setIsPrimary(model.getIsPrimary().getValue());

        platformEntity = platformRepository.save(platformEntity);

        model.setId(platformEntity.getId());

        return model;
    }

    /**
     * 判断帐号是存在
     *
     * @param account 帐号
     * @return true or false
     */
    @Override
    public boolean existsByAccount(@NonNull String account) {

        return platformRepository.existsByOpenId(account);
    }

    /**
     * 根据 accountId 获取帐号信息
     *
     * @param accountId 帐号ID
     * @return 帐号信息
     */
    @Override
    public AccountModel findById(long accountId) {

        AccountModel accountModel = new AccountModel();

        if (accountId > 0) {

            accountRepository
                    .findById(accountId)
                    .ifPresent(entity -> {
                        AccountStatusEnum statusEnum = AccountStatusEnum.get(entity.getStatus());
                        accountModel.setStatus(statusEnum);
                        BeanUtils.copyProperties(entity, accountModel);
                    });
        }

        return accountModel;
    }

    /**
     * 根据 openId 获取帐号平台信息
     *
     * @param account 帐号
     * @return 帐号平台信息
     */
    @Override
    public PlatformModel findByOpenId(@NonNull String account) {

        PlatformModel platformModel = new PlatformModel();

        platformRepository
                .findByOpenId(account)
                .ifPresent(value -> {
                    PrimaryEnum primaryEnum = PrimaryEnum.get(value.getIsPrimary());
                    platformModel.setIsPrimary(primaryEnum);

                    AccountTypeEnum typeEnum = AccountTypeEnum.get(value.getAccountType());
                    platformModel.setAccountType(typeEnum);

                    BeanUtils.copyProperties(value, platformModel);
                });

        return platformModel;
    }

    /**
     * 帐号是否是正常状态
     *
     * @param accountId 帐号ID
     * @return true or false
     */
    @Override
    public boolean isNormal(long accountId) {

        boolean result = false;

        if (accountId > 0 ) {

            Optional<AccountEntity> optional = accountRepository.findById(accountId);

            if (optional.isPresent()) {

                AccountEntity entity = optional.get();

                result = entity.getStatus() == AccountStatusEnum.NORMAL.getValue();
            }
        }

        return result;
    }
}
